﻿using Microsoft.Graphics.Canvas.Effects;
using Microsoft.Graphics.Canvas.Geometry;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using 纸片人.AttributeUsageFloder;
using 纸片人.InfoDataFolder;

// https://go.microsoft.com/fwlink/?LinkId=234238 上介绍了“空白页”项模板

namespace 纸片人.GpuPage
{
    [LastModified("2022-5-15", "create ColorReplacementPage.xaml")]
    [PageType("gpu", "颜色替换")]
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class ColorReplacementPage : Page
    {
        public ColorReplacementPage()
        {
            this.InitializeComponent();
            Init();
        }


        float effectWidth = 0;
        float effectHeight = 0;
        float previewWidth = 0;
        float previewHeight = 0;

        float offsetX, offsetY, scale, width, height;
        Vector2 pos;
        Color color;
        //是否有选择到颜色
        bool isSelectColor;

        //是否按下
        bool isPressed;
        LayerBitmapData bitmapData = new LayerBitmapData();

        private void Init()
        {
            selectPicture.Click += async (s, e) => { await bitmapData.SelectOneBitmapAsync(); CalcuationPosition(); canvas.Invalidate(); };
            canvas.CreateResources += (s, e) =>
            {
                CalcuationPosition();
                e.TrackAsyncAction(bitmapData.LoadOneShadeCodeAsync(Shaders.ShaderType.ColorReplacement).AsAsyncAction());
            };

            canvas.SizeChanged += (s, e) =>
            {
                CalcuationPosition();
            };
            canvas.Draw += (s, e) =>
            {
                Function.DrawGridGraphics(e.DrawingSession);

                if (bitmapData.oneBitmap != null && bitmapData.oneShaderCode != null)
                {
                    var previewTran = Function.CalcutateImageCenteredTransform(previewWidth, previewHeight, bitmapData.oneWidth, bitmapData.oneHeight);
                    previewTran.Source = bitmapData.oneBitmap;
                    e.DrawingSession.DrawImage(previewTran, 0, effectHeight);

                    

                   
                    PixelShaderEffect effect = new PixelShaderEffect(bitmapData.oneShaderCode)
                    {
                        Source1 = bitmapData.oneBitmap,
                        Properties = {["sourceColor"]=new Vector3(color.R/255f,color.G/255f,color.B/255f),
                        ["replaceColor"]=new Vector3(picker.Color.R/255f,picker.Color.G/255f,picker.Color.B/255),
                        ["threshold"] =(float)threshold.Value,
                        }
                    };
                    var effectTran = Function.CalcutateImageCenteredTransform(effectWidth, effectHeight, bitmapData.oneWidth, bitmapData.oneHeight);
                    if (isSelectColor)
                        effectTran.Source = effect;
                    else
                        effectTran.Source = bitmapData.oneBitmap;
                    e.DrawingSession.DrawImage(effectTran);

                    //是否进入范围
                    if (isPressed && (pos.X >= offsetX && pos.X <= offsetX + width && pos.Y >= offsetY && pos.Y <= offsetY + height))
                    {
                        //画三角形
                        CanvasPathBuilder builder = new CanvasPathBuilder(canvas);
                        builder.BeginFigure(pos);
                        builder.AddLine(pos - new Vector2(5, 5));
                        builder.AddLine(pos - new Vector2(-5, 5));
                        builder.EndFigure(CanvasFigureLoop.Closed);
                        CanvasGeometry geometry = CanvasGeometry.CreatePath(builder);
                        e.DrawingSession.FillGeometry(geometry, Colors.White);
                        e.DrawingSession.FillRoundedRectangle(new Rect(pos.X - 50, pos.Y - 100 - 5, 100, 100), 10, 10, Colors.White);
                        //采样位置
                        var usePx = (pos.X - offsetX) / scale;
                        var usePy = (pos.Y - offsetY) / scale;
                        //var scaleEffect = new ScaleEffect()
                        //{
                        //    Source = bitmapData.oneBitmap,
                        //    Scale = new Vector2(10f, 10f),
                        //};
                        e.DrawingSession.DrawImage(bitmapData.oneBitmap, pos.X - 50, pos.Y - 100 - 5, new Rect(usePx-50, usePy-50, 100, 100));
                        e.DrawingSession.DrawRectangle(new Rect(pos.X-1,pos.Y-56, 3, 3), Colors.Orange);
                        //e.DrawingSession.DrawLine(new Vector2(pos.X-6,pos.Y-55),new Vector2(pos.X-1,pos.Y-55), Colors.Red);
                        //e.DrawingSession.DrawLine(new Vector2(pos.X+6,pos.Y-55),new Vector2(pos.X+1,pos.Y-55), Colors.Red);
                        e.DrawingSession.DrawRoundedRectangle(new Rect(pos.X - 50, pos.Y - 100 - 5, 100, 100), 10, 10, Colors.Black);
                    }

                }
            };

            canvas.PointerPressed += (s, e) =>
            {
                isPressed = true;
                canvas.Invalidate();
            };

            canvas.PointerReleased += (s, e) =>
            {
                isPressed = false;
                canvas.Invalidate();

            };

            canvas.PointerMoved += (s, e) =>
            {
                if (!isPressed)
                    return;
                Point p = e.GetCurrentPoint(canvas).Position;
                pos = p.ToVector2();
                //是否进入范围
                if (bitmapData.oneBitmap != null && (p.X >= offsetX && p.X <= offsetX + width && p.Y >= offsetY && p.Y <= offsetY + height))
                {
                    var x = p.X - offsetX;
                    var y = p.Y - offsetY;
                    x = x / scale;
                    y = y / scale;
                    color = bitmapData.oneColors[(int)x + (int)y * bitmapData.oneWidth];
                    isSelectColor = true;

                    selectColor.Background = new SolidColorBrush(color);

                    canvas.Invalidate();
                }
            };

            picker.ColorChanged += (s, e) =>
            {
                canvas.Invalidate();
            };

            threshold.ValueChanged += (s, e) =>
            {
                canvas.Invalidate();
            };
        }

        void CalcuationPosition()
        {
            if (bitmapData.oneBitmap == null)
                return;
            var element = canvas;
            effectWidth = (float)element.ActualWidth;
            effectHeight = (float)element.ActualHeight * 0.7f;
            previewWidth = effectWidth;
            previewHeight = (float)element.ActualHeight * 0.3f;

            var mat = Function.CalcutateImageCenteredMat(previewWidth, previewHeight, bitmapData.oneWidth, bitmapData.oneHeight);
            scale = mat.M11;
            offsetX = mat.M31;
            offsetY = mat.M32 + effectHeight;
            width = scale * bitmapData.oneWidth;
            height = scale * bitmapData.oneHeight;
        }

    }
}
